<template>

    <div class="commonConfigForm" :page-name="localConfigOption.pageName" :style="commpStyle">
      <avue-form ref="form" :option="localConfigOption" v-model="form"></avue-form>
      <!-- 动态组件，用于统一弹框显示 -->

      <component ref="dialog" :is="dialogConfig.dialog" v-on="dialogConfig.vbindEvent" v-bind="dialogConfig.vbindParams">

        <template #content>
          <commonConfigForm
            v-if="dialogConfig.openModel == 'designScheme'"
            ref="commonConfigForm"
            :option="dialogConfig.uiContent"
            :readOnly="dialogConfig.readOnly"
            :disabled="dialogConfig.disabled"
            v-bind="dialogConfig.uiParam"
          >
          </commonConfigForm>
          <iframe v-else-if="dialogConfig.openModel == 'url' && uiContent.indexOf('isVue') >= 0" frameborder="0"
                  :src="dialogConfig.uiContent"></iframe>
          <router-view v-else-if="dialogConfig.openModel == 'url' && uiContent.indexOf('isVue') < 0"></router-view>
          <div v-else>{{ dialogConfig.uiParam }}</div>
        </template>
      </component>
    </div>
  </template>

  <script>
  import baseComp from './baseComp';

  let that;
  export default {
    name: "commonConfigForm",
    model: {
      prop: 'defaultData',
      event: 'configFormChange'
    },
    extends: baseComp,
    props: {
      value: [Object, String, Array],
      option: {
        type: Object,
        default: () => {
          return {
            column: [],
            menuBtn: false,
            emptyBtn: false,
            labelSuffix: "：",
            labelWidth: 150,
            gutter: 0,
            submitBtn: false,
            menuPosition: "center",
            submitText: "提交",
            labelPosition: "right",
            emptyText: "清空",
            theme: 'default',
            pageReq: {
              url: '',
              method: '',
              dicFormatter: '',
              reqParam: {
                objid: '',
                objtypeid: '',
                formId: '',
                partIndex: '',
                instanceUForm: [],
              }
            }
          }
        }
      },
      defaultData: {
        type: [Object, String, Array],
      },
      readOnly:{
        type: Boolean,
        default: false
      },
      disabled:{
        type: Boolean,
        default: false,
      },
      currentRow: {
        type: Object,
        default: () => {
        }
      },
      formId: {
        type: String,
        default: ''
      },
      jsLibraryPath: {
        type: String,
        default: ''
      },
      //资源类型ID
      resourceTypeId: {
        type: [String,Number],
        default: ''
      },
      //资源ID
      resourceId: {
        type: String,
        default: ''
      },
      //查询其他参数
      queryParam: {
        type: [Object, String],
        default: () => {
        }
      },
      //部件索引
      partIndex: {
        type: String,
        default: () => {
          return '';
        }
      }
    },
    watch: {
      option: {
        handler(val) {
          if (val) {
            if (this.isEmptyObject(val)) {
              return;
            }
            //设置主题色
            this.currentTheme = val.theme;
            //预处理原始界面配置函数
            this.$set(this, 'configOption', JSON.parse(JSON.stringify(val)));
            //变更option中的js函数对象
            this.parseJson(this.configOption);
            //复制原始界面配置json函数
            this.$set(this, 'localConfigOption', JSON.parse(JSON.stringify(val)));
            //获取当前根目录，判断能够获取界面中根据菜单配置栏生成的ueyeroot对象，如果没有则新生成一个对象
            if (!window.ueyeroot) {
              window.ueyeroot = {};
            }
            //判断是否有当前子系统对象，如果没有则新生成一个对象。并包含缓存、界面实例等数据内容
            let subsys = this.Subsystems ? this.Subsystems : "default";
            if (!window.ueyeroot[subsys]) {
              window.ueyeroot[subsys] = {};
            }
            window.ueyeroot[subsys][val.pageName] = {
              cache: {}
            }
            //遍历原始界面json数据，并重写json数据中的事件内容，将事件调度方式指向configOption本地对象中的事件函数，并将验证方式进行覆写。
            this.loopJsonConfig(this.localConfigOption, "", "ueyeroot." + subsys + "." + val.pageName, window.ueyeroot[subsys][val.pageName]);
            //加载界面初始化参数
            this.init();
            //用于定时更新表单
            window.setTimeout(() => {
              //更新表单字典内容，用于刷新远程字典数据。
              if (this.$refs.form) {
                this.$refs.form.updateDic();
              }
            }, 1000);
          }
        },
        immediate: true,  //刷新加载 立马触发一次handler
        deep: true  // 可以深度检测到 obj 对象的属性值的变化
      },
      defaultData: {
        handler(val) {
          this.form = val;
        },
        deep: true,
        immediate: true
      },
      form: {
        handler(val) {
          this.$emit("configFormChange", val);
        },
        deep: true,
        immediate: true
      }
    },
    data() {
      return {
        form: this.defaultData ? this.defaultData : {},
        configOption: {}, //原始的界面设计json内容
        localConfigOption: {}, //本地跳转复制界面设计json内容，用于截取组件点击事件，添加预处理事件前置-后置处理逻辑，并向下传递参数。
        fmId: this.formId, //表单ID
        resTypeId: this.resourceTypeId, //资源类型ID
        resId: this.resourceId, //资源ID
        qyParam: this.queryParam, //其他参数查询内容
        ptIndex: this.partIndex,//资源部件索引
        funcLibrary: {},
        dialogConfig: { //弹框配置内容
          dialog: '', //打开弹框（大/小弹框）
          dialogName: '', //弹框名称
          dialogWidth: '', //弹框宽度
          openModel: '', //打开模式
          designScheme: '', //弹框加载设计方案
          url: '', //弹框加载url地址
          uiContent: {}, //弹框界面UI json
          uiParam: {
            defaultData: {}, //页面数据内容
            resourceId: '', //资源ID
            resourceTypeId: '',//资源类型ID
            formId: '',//资源表单ID
            queryParam: {},//其他查询参数
            partIndex: ''//资源部件索引
          }, //界面渲染需要的参数
          vbindEvent: {}, //弹框加载事件
          vbindParams: {}, //弹框加载参数
        }
      }
    },
    created() {
      that = this;
      this.loadJsLibrary();
    },
    methods: {
      init() {
        this.queryPageInstanceData();
      },
      CustomDropDisplay(value, column) {
        if (value != "") {
          try {
            this.option.shTableData.forEach((item) => {
              if (column.prop == item.sourceValue) {
                //当前被点击的源
                if (item.dicValue == value) {
                  //当前源的选中值
                  if (this.option.group) {
                    this.option.group.forEach((every) => {
                      this.extracted(item, every.column, false);
                    });
                  }
                  this.extracted(item, this.option.column, false);
                  // throw new Error(
                  //     "点击当前的元素，已经达到显隐效果，跳出循环"
                  // );
                } else {
                  if (this.option.group) {
                    this.option.group.forEach((every) => {
                      this.extracted(item, every.column, true);
                    });
                  }
                  this.extracted(item, this.option.column, true);
                }
              }
            });
          } catch (e) {
            console.log(e.message);
            // throw e
          }
        } else {
          this.option.shTableData.forEach((item) => {
            if (this.option.group) {
              this.option.group.forEach((every) => {
                this.extracted(item, every.column, true);
              });
            }
            if (column.prop == item.sourceValue) {
              this.extracted(item, this.option.column, true);
            }
          });
        }
      },
      extracted: function (item, column, flag) {
        item.targetValue.forEach((el) => {
          let key = column.find(key => key.prop == el);
          if (key) {
            this.$set(key, "display", flag);
          }
        });
      },
      CustomEvents(id, ways, data) {
        this.eventHandler(id, ways, data, this.option.column)
        if (this.option.group) {
          this.option.group.forEach(every => {
            this.eventHandler(id, ways, data, every.column)
          })
        }
      },
      eventHandler(id, ways, data, array) {
        array.forEach(item => {
          if (id == item.prop) {
            //判断是否存在自定义事件
            if ('event' in item) { //有自定义事件
              if (item.event[ways] != undefined) {
                item.event[ways](data);
              }
            } else {//自带事件
              item[ways]({value: this.form[item['prop']], column: item})
            }
          }
        })
      },
      /**
       * 获取当前设计界面form表单数据
       */
      getFormData() {
        return this.form
      },

      /**
       * 动态执行函数
       * @param funcName 函数句柄名称
       */
      executeDynamic(funcName, value, column, params) {
        if (this.funcLibrary[funcName]) {
          this.funcLibrary[funcName](this, value, column, params);
        }
      },
      /**
       * 加载js类库
       */
      loadJsLibrary() {
        if (this.jsLibraryPath) {
          //动态加载js函数库
          let library = require('../projects' + this.jsLibraryPath);
          if (library) {
            this.funcLibrary = library.default;
          }
        }
      },

      /**
       * 根据事件属性配置，渲染对应的弹框和绑定弹框参数
       * @param path 点击当前组件在界面JSON数据中的点分制path路径
       * @param component 点击当前组件的JSON对象
       * @param funcName 当前点击执行的函数名称
       * @param response 当前funcName函数执行后的响应内容
       */
      executeRelationEventConfig(path, component, funcName, response) {
        //判断事件执行后的打开方式
        let eventsConfig = component['eventConfig'];
        //如果没有配置eventConfig属性的话，默认为void返回
        if (!eventsConfig) {
          return;
        }
        let eventConfig = eventsConfig[funcName];
        //获取事件对应的配置属性内容为空。
        if (!eventConfig) {
          return;
        }
        //获取funcName函数对应的属性配置内容，打开方式，小弹框，大弹框等，独立弹框，void。
        let openModel = eventConfig.openMode;
        if (!openModel || openModel == 'void') {
          return;
        }
        this.dialogConfig.dialog = openModel;
        //判断事件执行后操作，如果没有配置或则配置void，则直接返回，不再继续往下执行。
        if (!this.dialogConfig.dialog) {
          return;
        }
        //赋值动态组件打开方式
        this.dialogConfig.openModel = eventConfig.openContent;
        //赋值弹框名称
        this.dialogConfig.dialogName = eventConfig.dialogName;
        //赋值弹框宽度
        this.dialogConfig.dialogWidth = eventConfig.openWidth;
        //赋值设计方案
        this.dialogConfig.designScheme = eventConfig.designScheme;
        //赋值url地址
        this.dialogConfig.url = eventConfig.url;
        //初始化页面设计响应内容和方式
        //创建弹框加载事件
        this.createDialogVbindEvent();
        //创建弹框加载参数
        this.createDialogVbindParams(path, response);
        //创建弹框加载内容
        this.getDialogDesignUIContent(response);
      },

      /**
       * 创建组件事件绑定，重写基类组件中的事件绑定函数，需要在事件绑定过程中添加内容参数等传递，
       * 只有大弹框才能支持此处函数绑定过程，以后待优化设计后，方可去掉。
       */
      createDialogVbindEvent() {
        let openMode = this.dialogConfig.dialog;
        let event = {};
        if (openMode == 'commonDialog') {
          event.closeDialog = () => {
            this.closeBigDialog();
          }
          event.okClick = () => {
            // if (valid) {
            // done()
            let commp = this.getTargetDialogCommp();
            if (!commp) {
              return
            }
            let formData = this.$refs.commonConfigForm.getFormData();
            //将事件传递到外层进行数据逻辑处理
            let okClick = commp['event']['commonDialogOkClick'];
            if (okClick && typeof okClick == 'function') {
              okClick(formData);
            }
            // } else {
            //     return false;
            // }
            // this.$refs.commonConfigForm.$refs.form.validate((valid, done, msg) => {

            // })
          }
        } else if (openMode == 'commonMiniDialog') {
          // do something
        } else if (openMode == 'independentWindow') {
          //do something
        } else {
          //do something
        }
        this.dialogConfig.vbindEvent = {...event};
      },
      closeBigDialog() {
        //封装拼装请求体对象参数
        let commp = this.getTargetDialogCommp();
        if (!commp) {
          return
        }
        let formData = this.$refs.commonConfigForm.getFormData();
        //将事件传递到外层进行数据逻辑处理
        let closeClick = commp['event']['commonDialogCloseClick'];
        if (closeClick && typeof closeClick == 'function') {
          closeClick(formData);
        }
        this.dialogConfig.vbindParams.dialogFormVisible = false;
      },
      /**
       * 绑定参数，给组件动态绑定参数
       * @returns {{}}
       */
      createDialogVbindParams(path, response) {
        let openMode = this.dialogConfig.dialog;
        let dialogName = this.dialogConfig.dialogName;
        let dialogWidth = this.dialogConfig.dialogWidth;
        let params = {};
        params.path = path;
        params.readOnly = response && response.readOnly ? response.readOnly : false;
        params.theme = this.currentTheme;
        if (openMode == 'commonDialog') {
          if (dialogName) {
            params.kpiTitle = dialogName;
          } else {
            params.kpiTitle = '大弹框';
          }
          params.dialogFormVisible = true;
        } else if (openMode == 'commonMiniDialog') {
          if (dialogName) {
            params.title = dialogName;
          } else {
            params.title = '小弹框';
          }
          if (dialogWidth) {
            params.width = dialogWidth;
          }
          params.add = true;
        } else if (openMode == 'independentWindow') {
          //do something
        } else {
          //do something

        }
        this.dialogConfig.vbindParams = {...params};
      },

      /**
       * 关闭弹框
       */
      closeDialog(openMode) {
        if (openMode == 'commonDialog') {
          // this.dialogConfig.vbindParams.dialogFormVisible = false;
          this.closeBigDialog();
        } else if (openMode == 'commonMiniDialog') {
          this.dialogConfig.vbindParams.add = false;
        } else if (openMode == 'independentWindow') {
          //do something
        } else {
          //do something

        }
      },

      /**
       * 打开弹框
       */
      openDialog(openMode) {
        if (openMode == 'commonDialog') {
          this.dialogConfig.vbindParams.dialogFormVisible = true;
        } else if (openMode == 'commonMiniDialog') {
          this.dialogConfig.vbindParams.add = true;
        } else if (openMode == 'independentWindow') {
          //do something
        } else {
          //do something

        }
      },

      /**
       * 弹框设计界面内部获取与弹框同级别的界面渲染器对象
       */
      // getRootNode() {
      //     let commonConfigForm= this.$parent.$parent.$parent;
      //     return commonConfigForm;
      // },

      /**
       * 并关闭弹框显示
       */
      // closeDefaultDialog(){
      //     let commonConfigForm = this.getRootNode();
      //     let openMode = commonConfigForm.component;
      //     if (openMode == 'commonDialog'){
      //         commonConfigForm.vbindParams.dialogFormVisible = false;
      //     }else if (openMode == 'commonMiniDialog'){
      //         commonConfigForm.vbindParams.add = false;
      //     }else if(openMode == 'independentWindow'){
      //         //do something
      //     }else {
      //         //do something
      //
      //     }
      // },


      test(param){
        if(param){
          this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            if(param){
              this.$myAxios.request('post', '/uavMesh/resource/deleteResourceFormData',param).then((res)=>{
                if(res.data.code == 200){
                  let that = this.getCommonConfigFormUpLoop('form',this,'broadcastList');
                  that.closeDialog('commonMiniDialog');
                  that.getCommpInstance("broadcastTable").getInit();
                  this.$message({
                    type: 'success',
                    message: '删除成功!'
                  });
                }else{
                  this.$message({
                    type: 'error',
                    message: '删除失败!'
                  });
                }
              })
            }
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            });
          });
        }
        else{
          this.$message.info("请先选择数据进行删除");
          return;
        }
      },




      /**
       * 获取设计方案界面内容
       */
      async getDialogDesignUIContent(response) {
        let openMode = this.dialogConfig.openModel;
        let designScheme = this.dialogConfig.designScheme;
        let url = this.dialogConfig.url;
        //获取设计方案
        if (openMode == 'designScheme' && designScheme) {
          await this.$myAxios
            .request('post', '/uavMesh/operation/getOperationUiContentByProcessKey', {processKey: designScheme})
            .then((res) => {
              if (res.data.code == 200) {
                let data = res.data.data.design.uiContent;
                data.pageName = designScheme;
                data.theme = this.currentTheme;
                data.readOnly = response && response.readOnly ? response.readOnly : false;
                data.disabled = response && response.disabled ? response.disabled : false;
                this.dialogConfig.uiContent = data;
                this.dialogConfig.readOnly = response && response.readOnly ? response.readOnly : false;
                this.dialogConfig.disabled = response && response.disabled ? response.disabled : false;
              } else {
                this.$message.error('获取设计方案界面失败！')
              }
            })
        }
        //响应原始内容
        else if (openMode == 'originalData') {
          // do something
        }
        //响应URL地址显示内容
        else if (openMode == 'url' && url) {
          this.dialogConfig.uiContent = url;
          //判断当前url不包含isVue，则通过路由方式跳转
          if (this.dialogConfig.uiContent.indexOf('isVue') < 0) {
            await this.$router.push({path: this.dialogConfig.uiContent, query: this.dialogConfig.uiParam});
          }
        }
      },
      /**
       * 获取弹框目标组件
       */
      getTargetDialogCommp() {
        let path = this.$refs.dialog.path;
        if (path) {
          let pathArray = path.split(".");
          let targetPath = pathArray.slice(0, 2);
          let commp = this.queryCompJsonByPath(0, targetPath, this.configOption);
          return commp;
        }
      },

      /**
       * 遍历json数据中的event事件函数，并重写事件内容，在函数中加入执行事件属性配置的判定条件
       * @param {界面加载json数据} json
       * @param {json全path路径} path
       * @param {json中包含界面、组件的页面path路径} pagePath
       * @param {界面根json对象} uRoot
       */
      loopJsonConfig(json, path, pagePath, uRoot) {
        for (const key in json) {
          //如果对象类型为object类型且数组长度大于0 或者 是对象 ，继续递归解析
          let element = json[key]
          if (element) {
            if (element.length > 0 && typeof (element) == "object" || typeof (element) == "object") {
              //判断是否需要覆盖事件对象
              if (key != 'event') {
                //组装path路径
                element.path = (path ? path + "." : '') + key;

                this.loopJsonConfig(element, element.path, pagePath, uRoot);
              } else {
                //重置event对象函数内容，让其执行本地函数钩子，通过本地函数钩子转向调用原始函数，让其指向原始函数内容体
                for (let elementKey in element) {
                  element[elementKey] = async (path, funcName, params) => {
                    console.log('当前执行函数', funcName);
                    path = path.substring(0, path.lastIndexOf("."))
                    //查找原始函数，并执行原始函数调度
                    let keys = path.split(".");
                    //根据path路径查找本地组件json对象
                    let component = this.queryCompJsonByPath(0, keys, this.configOption);
                    //加入函数执行参数
                    //判断组件自带click、change、blur、focus等函数是否存在
                    let func = component[funcName];
                    if (undefined === func || !func) {
                      //外部申明自定义自行函数
                      func = component['event'][funcName];
                    }
                    //处理函数入参数。
                    if (params) {
                      if (Array.isArray(params)) {
                        for (let paramsIndex in params) {
                          if (!params[paramsIndex]) {
                            params[paramsIndex] = this.form;
                          }
                        }
                      } else {
                        params = [params];
                      }
                    }
                    //执行对应的函数体
                    let response = await func.apply(null, params);
                    if (response == 'void') {
                      return;
                    }
                    //将函数响应内容赋值给弹框渲染参数
                    if (response) {
                      this.$set(this.dialogConfig, 'uiParam', response);
                    }
                    console.log("大界面传入的数据内容", this.dialogConfig.uiParam)
                    //调用本地函数，执行事件对应属性配置操作。
                    this.executeRelationEventConfig(path, component, funcName, response);
                  };
                }
              }
            }
            else {
              //判断当前对象是否为组件对象
              if (key == "prop") {
                if (json['params']) {
                  pagePath = (pagePath ? pagePath + "." : "") + element;
                  json['params'].pagePath = pagePath;
                  json['params'].theme = this.configOption.theme;
                  uRoot = uRoot[element] = {
                    cache: {},
                    name: json['label'] ? json['label'] : json['title'],
                    pagePath: pagePath
                  }
                }
                if (json['value'] && !this.form[json[key]]) {
                  this.form[json[key]] = json['value'];
                }
              }
              //判断字符内容中是否有动态参数，如果有则替换字符串中动态参数
              let regexp = /\$\{\w*\}/;
              if (regexp.exec(element)) {
                element = element.replace("${resourceId}", this.resId);
                element = element.replace("${formId}", this.fmId);
                element = element.replace("${resourceTypeId}", this.resTypeId);
                element = element.replace("${partIndex}", this.ptIndex);
                json[key] = element;
              }
              //将json中的js函数字符串转换为js函数对象，判断js函数字符串的正则表达式
              let funcRegexp = /function\s+\w*\((\w*,?\s*)*\)|\(\{?(\w*,?\s*)*\}?\)\s*=>\s*/
              if (element.indexOf && funcRegexp.test(element)) {
                try {
                  //判断当前json对象是否有path路径，如果有则用原始函数，如果没有则不管。
                  if (json.path) {
                    //判断当前json值是否为JSON字符串，如果是转换为json对象
                    json[key] = eval(element);
                  }
                } catch (e) {
                  console.error("转换js函数字符串为js函数时异常：", e, "函数体内容为：", element)
                }
              }
              //自定义正则验证格式化
              else if (key == 'pattern' && element) {
                let regex = '';
                if (element.indexOf("/") == 0) {
                  regex = element.substring(element.indexOf("/") + 1, element.length - 1);
                } else {
                  regex = element;
                }
                if (!json.rules) {
                  json.rules = [];
                }
                let customRules = [];
                //重构正则验证对象，用于自定义字段格式验证
                let regExp = new RegExp(regex)
                if (json.rules.length > 1) {
                  json.rules.forEach((rule) => {
                    //判断是否有自定义验证
                    if (rule.pattern){
                            customRules.push({
                                validator: (ru, value, callback) => {
                                    if (regExp.test(value)){
                                        callback();
                                    }else {
                                        callback(new Error(json.label+'格式不匹配！'))
                                    }
                                },
                                trigger: 'change'
                            })
                        }
                  })
                } else {
                    customRules.push({
                        validator: (ru, value, callback) => {
                            if (regExp.test(value)){
                                callback();
                            }else {
                                callback(new Error(json.label+'格式不匹配！'))
                            }
                        },
                        trigger: 'change',
                    })
                }
                if(json.required){
                    customRules.push({
                        required: true,
                        message: json.label+'必须填写',
                    })
                }
                json.rules = customRules;
              }
            }
          }
        }
      },

      /**
       * 递归遍历json key属性和值，将json对象中的值（js函数字符串转换为js函数对象）
       */
      parseJson(jsonObj) {
        // 循环所有键
        for (const key in jsonObj) {
          //如果对象类型为object类型且数组长度大于0 或者 是对象 ，继续递归解析
          let element = jsonObj[key]
          if (element) {
            if (element.length > 0 && typeof (element) == "object" || typeof (element) == "object") {
              this.parseJson(element);
            } else {
              //将json中的js函数字符串转换为js函数对象，判断js函数字符串的正则表达式
              let funcRegexp = /function\s+\w*\((\w*,?\s*)*\)|\(\{?(\w*,?\s*)*\}?\)\s*=>\s*/
              if (element.indexOf && funcRegexp.test(element)) {
                try {
                  //判断当前json值是否为JSON字符串，如果是转换为json对象
                  jsonObj[key] = eval(element);
                } catch (e) {
                  console.error("转换js函数字符串为js函数时异常：", e, "函数体内容为：", element)
                }
              }
            }
          }
        }
      },
      /**
       * 验证表单数据内容
       * @param callback 验证表单回调函数，验证通过后执行方法
       */
      async validateForm(callback, failCallBack) {
        await this.$refs.form.validate((valid, done, msg) => {
          try {
            if (valid) {
              callback();
            } else {
              if (failCallBack) {
                failCallBack();
              }
              console.error("验证失败", msg)
              return false;
            }
          } finally {
            done()
          }

        })
      },

      /**
       * 初始化加载界面所需实例数据
       */
      queryPageInstanceData() {
        if (!this.configOption.pageReq) {
          return;
        }
        let url = this.configOption.pageReq.url;
        //当前没配置请求路径地址则直接返回退出，不进行下步操作。
        if (!url) {
          return;
        }
        let method = this.configOption.pageReq.method;
        let reqParam = this.configOption.pageReq.reqParam
        let instanceUForm = {};
        for (let item of reqParam.instanceUForm) {
          instanceUForm[item.label] = item.value;
        }
        reqParam.instanceUForm = instanceUForm;
        if (!reqParam.objid) {
          reqParam.objid = this.resId;
        }
        if (!reqParam.objtypeid) {
          reqParam.objtypeid = this.resTypeId;
        }
        if (!reqParam.formId) {
          reqParam.formId = this.fmId;
        }
        if (!reqParam.partIndex) {
          reqParam.partIndex = this.ptIndex;
        }
        ajax.request(method, url, reqParam).then((res) => {
          res = res.data;
          if (!res.data) {
            return;
          }
          let dicFormatter = this.configOption.pageReq.dicFormatter;
          if (dicFormatter) {
            if (typeof dicFormatter != 'function') {
              dicFormatter = eval(dicFormatter);
            }
            let data = dicFormatter(res)
            //将返回数据合并到实例表单中，如果有相同属性则覆盖，如果没有则新增
            this.form = {...this.form, ...data};
          }
        }).catch((err) => {
          console.error("查询界面数据异常", err);
        })
      },

      /**
       * 获取组件实列对象
       */
      getCommpInstance(prop) {
        try {
          let propRef = this.$refs.form.getPropRef(prop);
          if (propRef) {
            return propRef.$refs.temp;
          }
        } catch (err) {
          return null;
        }
        return null;
      },

      /**
       * 获取设计器组件下嵌套的组件
       */
      getCommpInstanceDownLoop(prop, commp) {
        if (!commp) {
          return null;
        }
        let commp_;

        function loop(prop, commp) {
          if (typeof commp.$el.getAttribute == "function") {
            let prop_ = commp.$el.getAttribute("prop");
            if (prop == prop_) {
              commp_ = commp;
              return;
            }
            for (let child of commp.$children) {
              loop(prop, child);
            }
          } else {
            for (let child of commp.$children) {
              loop(prop, child);
            }
          }
        }

        loop(prop, commp);
        return commp_;
      },


      /**
       *
       * 递归向上查找指定refName属性组件
       * @param refName 需要查找组件的ref属性名称
       * @param commp 指定从那个组件开始向上查找
       * @param pageName 指定界面名称
       */
      getCommonConfigFormUpLoop(refName, commp, pageName) {
        if (!commp) {
          return null;
        }
        let commp_;

        function loop(refName, commp, pageName) {
          if (commp && !commp.$refs[refName]) {
            // 如果当前组件没有找到 ref，可以递归查找子组件
            let parent = commp.$parent;
            if (parent) {
              loop(refName, parent, pageName);
            }
          } else {
            //定义当前找到的组件元素
            let currentCommp;
            // 如果找到，处理逻辑（例如打印或操作元素）
            console.log('Found ref:', commp.$refs[refName]);
            let classAttribute = commp.$el.getAttribute("class");
            if (classAttribute.indexOf("commonConfigForm") >= 0) {
              currentCommp = commp;
            } else {
              currentCommp = commp.$parent;
            }
            //获取界面名称
            let pageName_ = currentCommp.$el.getAttribute("page-name");
            //判断当前组件是否为指定页面组件
            if (pageName_ != pageName) {
              let parent = currentCommp.$parent;
              loop(refName, parent, pageName);
            } else {
              commp_ = currentCommp;
              return;
            }
          }
        }

        loop(refName, commp, pageName);
        return commp_;
      },

      /**
       * 递归向下找指定refName属性组件
       * @param refName 需要查找组件的ref属性名称
       * @param commp 指定从那个组件开始向上查找
       * @param pageName 指定界面名称
       */
      getCommonConfigFormDownLoop(refName, commp, pageName) {
        if (!commp) {
          return null;
        }
        let commp_;

        function loop(refName, commp, pageName) {
          if (!commp.$refs[refName]) {
            // 如果当前组件没有找到 ref，可以递归查找子组件
            let childs = commp.$children;
            if (childs && childs.length > 0) {
              for (let child of childs) {
                loop(refName, child, pageName);
              }
            }
          } else {
            //定义当前找到的组件元素
            let currentCommp;
            //当前深度减1，如果深度为0，则表示查找到所需的组件
            let classAttribute = commp.$el.getAttribute("class");
            if (classAttribute.indexOf("commonConfigForm") >= 0) {
              currentCommp = commp;
            } else {
              currentCommp = commp.$parent;
            }
            //获取界面名称
            let pageName_ = currentCommp.$el.getAttribute("page-name");
            if (pageName_ != pageName) {
              // 如果当前组件没有找到 ref，可以递归查找子组件
              let childs = commp.$children;
              if (childs && childs.length > 0)
                for (let child of childs) {
                  loop(refName, child, pageName);
                }
            } else {
              commp_ = currentCommp;
              return;
            }
          }
        }

        loop(refName, commp, pageName);
        return commp_;
      },

      /**
       * 禁用指定字段或则一批字段
       */
      disabledColumn(column, disabled) {
        if (null == disabled || undefined == disabled) {
          disabled = true;
        }
        let func = (targetColumn, column) => {
          targetColumn.forEach(itemColumn => {
            if (column) {
              let item = column.find(item => item.prop == itemColumn);
              if (item) {
                this.$set(item, 'disabled', disabled);
              }
            }
          })
        }
        let targetColumn = [];
        if (Array.isArray(column)) {
          targetColumn.push(...column);
        } else {
          targetColumn.push(column);
        }
        func(targetColumn, this.localConfigOption.column);
        if (this.localConfigOption.group) {
          for (let groupIndex in this.localConfigOption.group) {
            let item = this.localConfigOption.group[groupIndex];
            func(targetColumn, item.column);
          }
        }
      },
      /**
       * 排除指定元素进行禁用启用
       */
      disabledExcludeColumn(column, disabled) {
        if (null == disabled || undefined == disabled) {
          disabled = true;
        }
        let func = (column, targetColumn) => {
          //查看需要排除的队列中是否包含指定元素
          column.forEach(item => {
            //查看需要排除的队列中是否包含指定元素
            let columnName = targetColumn.find(itemColumn => {
              return item.prop == itemColumn
            });
            if (!columnName) {
              this.$set(item, 'disabled', disabled);
            } else {
              this.$set(item, 'disabled', !disabled);
            }
          })
        }
        let targetColumn = [];
        if (Array.isArray(column)) {
          targetColumn.push(...column);
        } else {
          targetColumn.push(column);
        }
        func(this.localConfigOption.column, targetColumn)
        if (this.localConfigOption.group) {
          this.localConfigOption.group.forEach(item => {
            func(item.column, targetColumn)
          })
        }
      },

      /**
       * 交替显示，隐藏组件
       * @param column 交替显示隐藏组件
       */
      triggerDisplayColumn(column) {
        let func = (targetColumn, column) => {
          targetColumn.forEach((itemColumn) => {
            let item = column.find(item => item.prop == itemColumn);
            if (item) {
              this.$set(item, 'display', !item.display);
            }
          })
        }
        let targetColumn = []
        if (Array.isArray(column)) {
          targetColumn.push(...column);
        } else {
          targetColumn.push(column);
        }
        func(targetColumn, this.localConfigOption.column);
        if (this.localConfigOption.group) {
          this.localConfigOption.group.forEach((groupItem) => {
            func(targetColumn, groupItem.column);
          })
        }
      },

      /**
       * 查找组件集合中的组件内容
       * @param column 传入的组件prop名称
       */
      getColumn(column) {
        let columnItem;
        let func = (targetColumn, column) => {
          targetColumn.forEach((itemColumn) => {
            columnItem = column.find(item => item.prop == itemColumn);
          })
        }
        let targetColumn = []
        if (Array.isArray(column)) {
          targetColumn.push(...column);
        } else {
          targetColumn.push(column);
        }
        func(targetColumn, this.localConfigOption.column);
        if (columnItem) {
          return columnItem;
        }
        if (this.localConfigOption.group) {
          this.localConfigOption.group.forEach((groupItem) => {
            func(targetColumn, groupItem.column);
          })
        }
        return columnItem;
      },

      /**
       * 显示或则隐藏指定
       */
      displayColumn(column, display) {
        if (null == display || undefined == display) {
          display = true;
        }
        let func = (targetColumn, column) => {
          targetColumn.forEach((itemColumn) => {
            let item = column.find(item => item.prop == itemColumn);
            if (item) {
              this.$set(item, 'display', display);
            }
          })
        }
        let targetColumn = []
        if (Array.isArray(column)) {
          targetColumn.push(...column);
        } else {
          targetColumn.push(column);
        }
        func(targetColumn, this.localConfigOption.column);
        if (this.localConfigOption.group) {
          this.localConfigOption.group.forEach((groupItem) => {
            func(targetColumn, groupItem.column);
          })
        }
      },

      /**
       * 显示隐藏除指定字段以外的内容
       */
      displayExcludeColumn(column, display) {
        if (null == display || undefined == display) {
          display = true;
        }
        let func = (targetColumn, column) => {
          column.forEach(item => {
            //查看需要排除的队列中是否包含指定元素
            let columnName = targetColumn.find(itemColumn => {
              return item.prop == itemColumn
            });
            if (!columnName) {
              this.$set(item, 'display', display);
            } else {
              this.$set(item, 'display', !display);
            }
          })
        }
        let targetColumn = []
        if (Array.isArray(column)) {
          targetColumn.push(...column);
        } else {
          targetColumn.push(column);
        }
        func(targetColumn, this.localConfigOption.column);
        if (this.localConfigOption.group) {
          this.localConfigOption.group.forEach(item => {
            func(targetColumn, item.column);
          })
        }
      },

      /**
       * 设置字段值
       */
      setColumnData(column, data) {
        this.$set(this.form, column, data);
      },

      /**
       * 批量设置值
       */
      setBatchData(dataObj) {
        let form_ = {...this.form, ...dataObj};
        this.$set(this, 'form', form_);
      },

      /**
       * 设置字段dicData
       */
      setColumnDicData(prop, dicData) {
        let column = this.localConfigOption.column.find(item => {
          return item.prop == prop;
        });
        // column.dicData = dicData;
        this.$set(column, 'dicData', dicData);
      },

      /**
       * 刷新表单字典数据
       */
      refreshForm(prop) {
        //更新表单字典内容，用于刷新远程字典数据。
        if (prop) {
          this.$refs.form.updateDic(prop);
        } else {
          this.$refs.form.updateDic();
        }
      },

      /**
       * 获取表单指定列数值
       */
      getColumnData(column) {
        return this.form[column];
      },

      resetFields(){
        return this.$refs.form.resetFields();
      }
    }
  }
  </script>

  <style lang="less" scoped>
  //去除首页分组栏样式
  .commonConfigForm {
    width: 100%;
    //height: 100%;
    position: relative;

    /deep/ .el-form {
      // width: 100%;
      height: 100%;
      position: relative;

      .el-form {
        // width: 100%;
        height: 100%;
        position: relative;

      }

      .el-row {
        // width: 100%;
        height: 100%;
        position: relative;

      }

      // .avue-group{
      //     width: 100%;
      //     height: 100%;
      //     position: relative;
      // }
      .el-collapse {
        // width: 100%;
        height: 100%;
        position: relative;

      }

      .el-collapse-item {
        // width: 100%;
        height: 100%;
        position: relative;
      }

      .el-collapse-item__wrap {
        // width: 100%;
        height: 100%;
        position: relative;
      }

    }

    /deep/ .el-collapse-item__content {
      // width: 100%;
      height: 100%;
      position: relative;

      .avue-form__group {
        width: 100%;
        height: 100%;
        position: relative;
      }

      .avue-form__row {
        // width: 100%;
        height: 100%;
        //position: relative;
      }

      .el-form-item {
        // width: 100%;
        height: 100%;
        //position: relative;
      }

      .el-form-item__content {
        // width: 100%;
        height: 100%;
        //position: relative;
      }

      .el-form-item__content > div {
        // width: 100%;
        height: 100%;
        //position: relative;
      }
    }

    /deep/ .el-divider--horizontal {
      margin: 0px !important;
    }

    /deep/ .avue-group {
      .el-collapse {
        border-top: none;
        border-bottom: none;
        //avue分组样式
        .el-collapse-item__header {
          border: none;

          .avue-group__header {
            text-align: left;
            margin-left: 10px;

            .avue-group__title {
              font-size: 16px;
              font-weight: normal;
              width: max-content;
            }
          }

          .el-collapse-item__arrow {
            margin: 0 8px 0 8px
          }

          &::after {
            content: '';
            border-bottom: 1px dashed #000;
            width: 100%;
            display: inline-block;
          }
        }

        .el-collapse-item__content {
          .avue-form__row {
            padding-left: 0px !important;
            padding-right: 0px !important;
          }
        }

        .el-collapse-item__wrap {
          border-bottom: none;

          .avue-form__group {
            .el-form-item {
              .el-input-number {
                width: 100% !important;
              }
            }
          }
        }
      }
    }

    /deep/ .avue-group--header {
      .el-collapse-item__header {
        display: none;
      }
    }

    // 全局按钮样式
    /deep/ .el-button--success {
      color: #3dbf8f;
      background: #ffffff;
      border-radius: 2px;
      border: 1px solid #3dbf8f;
      cursor: pointer;
    }

    /deep/ .el-button--success:hover {
      background: rgb(216, 248, 238);
    }

    /deep/ .el-button--success:active {
      background: rgb(65, 189, 142);
      color: #FFFFFF;
    }

    /deep/ .el-button--primary {
      color: var(--theme_color);
      background: #ffffff;
      border-radius: 2px;
      border: 1px solid var(--theme_color);
      cursor: pointer;
    }

    /deep/ .el-button--primary:hover {
      background: rgb(211, 218, 251);
    }

    /deep/ .el-button--primary:active {
      background: rgb(44, 104, 237);
      color: #FFFFFF;
    }

    /deep/ .el-button--danger {
      color: #ff6161;
      background: #ffffff;
      border-radius: 2px;
      border: 1px solid #ff6161;
      cursor: pointer;
    }

    /deep/ .el-button--danger:hover {
      background: rgb(255, 229, 229);
    }

    /deep/ .el-button--danger:active {
      background: rgb(255, 95, 95);
      color: #FFFFFF;
    }

    /deep/ .el-button--info {
      color: #333333;
      background: #FFF;
      border-radius: 2px;
      border: 1px solid #e1e5ec;
      cursor: pointer;
    }

    /deep/ .el-button--info:hover {
      background-color: #dddfe4;
    }

    /deep/ .el-button--info:active {
      background: #909399;
      border-color: #909399;
      color: #FFFFFF;
    }
    /deep/ .el-button--mini {
      padding: 7px 10px !important;
      font-size: 14px !important;
    }
    /deep/ .el-button--small{
      font-size: 14px !important;
    }
  }
  </style>
  <style>
  /* 滚动条样式********************************** */
  ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }

  /* Track */
  ::-webkit-scrollbar-track {
    /* // background: rgb(255, 255, 255); */
    border-radius: 4px;
  }

  /* Handle */
  ::-webkit-scrollbar-thumb {
    background: rgb(201, 201, 202);
    border-radius: 4px;
  }

  /* //Handle on hover */
  ::-webkit-scrollbar-thumb:hover {
    background: rgb(162, 162, 163);
  }

  /* // 表格底部横条样式 */
  .el-table--border::after, .el-table--group::after, .el-table::before {
    position: inherit;
  }
  </style>
